package com.aplink.generic.util.convertcount;

import android.app.Activity;
import android.view.View;

import com.aplink.generic.constant.SqlDataType;
import com.aplink.generic.pojo.GenericAttribute;
import com.aplink.generic.pojo.GenericObject;
import com.aplink.generic.pojo.ObjPropInfo;
import com.aplink.generic.pojo.ObjPropValue;
import com.aplink.generic.pojo.xml.TableInfo;

import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;

public class GenericConverter {

    /**
     * This function is to convert to dataType Integer abc =
     * GenericConverter.convert("5", Integer.class);
     */
    public static <I, O> O convert( I input, Class<O> outputClass )
            throws Exception {
        return input == null ? null : outputClass.getConstructor( String.class )
                .newInstance( input.toString() );
    }

    /**
     * This function is to convert into a GenericAttribute from name, dataType,
     * value
     */
    public static GenericObject convertObjPropValueIntoGenericObject(
            ArrayList<ObjPropValue> objPropValueList, String tableName,
            ArrayList<ObjPropInfo> objPropInfoList ) {

        if ( tableName == "" ) {
            return null;
        }

        final GenericObject genericObject = new GenericObject();
        genericObject.setObjectMappingName( tableName );
        final ArrayList<GenericAttribute<?, ?>> attributeList = new ArrayList<GenericAttribute<?, ?>>();

        for ( ObjPropValue propValue : objPropValueList ) {
            String attributeID = propValue.getObjectPropID();
            SqlDataType dataType = GenericFilter
                    .getDataTypeOfAttributeFromObjectPropMappingName(
                            objPropInfoList, attributeID );
            String value = propValue.getAttribute().getValue().toString();

            boolean isInside = GenericFilter.checkAttributedInsideContentData(
                    attributeID, tableName, objPropInfoList );

            if ( isInside == true ) {
                final GenericAttribute<?, ?> attribute = GenericConverter
                        .getGenericAttribute( attributeID, dataType, value );
                attributeList.add( attribute );
            }
        }
        genericObject.setAttributeList( attributeList );
        return genericObject;

    }

    public static String getCreateColumnsCommands( TableInfo currentTable ) {

        String createCommand = "";
        int countIskey = 0;
        for ( int index = 0 ; index < currentTable.getmColumnList().size() ; index++ ) {
            final ObjPropInfo objPropInfo = currentTable.getmColumnList().get(
                    index );

            // add column name
            createCommand += objPropInfo.getObjectProperty();

            // add column data type
            final SqlDataType dataType = objPropInfo.getDataType();
            createCommand += " " + dataType.toString();

            // add isKey and auto increment if this is a key
            if ( objPropInfo.isKey() ) {
                createCommand += " PRIMARY KEY ";
                if ( objPropInfo.isAuto() == true ) {
                    createCommand += " AUTOINCREMENT";
                }
                countIskey++;
            }

            // add with command
            createCommand += ",";
        }

        if ( countIskey > 1 ) {
            return "";
        }

        // remove last comma in this command
        if ( ( createCommand.length() > 0 )
                && ( createCommand.charAt( createCommand.length() - 1 ) == ',' ) ) {
            createCommand = createCommand.substring( 0,
                    createCommand.length() - 1 );
        }
        return createCommand;
    }

    /**
     * This function is to convert into a GenericAttribute from name, dataType,
     * value
     */

    public static GenericAttribute<?, ?> getGenericAttribute( String name,
                                                              SqlDataType dataType, String value ) {

        if ( ( value == null ) || value.equals( "" ) ) {
            return new GenericAttribute<String, String>( name, value );
        } else if ( dataType.equals( SqlDataType.INTEGER ) ) {
            return new GenericAttribute<String, Integer>( name,
                    (Integer) dataType.parse( value ) );
        } else if ( dataType.equals( SqlDataType.LONG ) ) {
            return new GenericAttribute<String, Long>( name,
                    (Long) dataType.parse( value ) );
        } else if ( dataType.equals( SqlDataType.DOUBLE ) ) {
            return new GenericAttribute<String, Double>( name,
                    (Double) dataType.parse( value ) );
        } else if ( dataType.equals( SqlDataType.TEXT ) ) {
            return new GenericAttribute<String, String>( name, value );
        } else if ( dataType.equals( SqlDataType.DATETIME ) ) {
            return new GenericAttribute<String, Date>( name,
                    (Date) dataType.parse( value ) );
        }
        return null;

    }

    /**
     * Convenience method of findViewById, this is used for activity
     */
    @SuppressWarnings("unchecked")
    public static <T extends View> T getView( Activity activity, int id ) {
        return (T) activity.findViewById( id );
    }

    /**
     * Convenience method of findViewById of parent, this is used for parent
     * view
     */
    @SuppressWarnings("unchecked")
    public static <T extends View> T getView( View parent, int id ) {
        return (T) parent.findViewById( id );
    }

    /**
     * This function is to convert a GenericObjectList to hashmap<String,String>
     * of two attributes in GenericObject as you want
     */
    public static Hashtable<String, String> parseObjectListToHashTable(
            ArrayList<GenericObject> objectList, String textAttribute,
            String valueAttribute ) {

        final Hashtable<String, String> KeyValue = new Hashtable<String, String>();
        KeyValue.clear();

        for ( int i = 0 ; i < objectList.size() ; i++ ) {
            // we get the current GenericObject
            // each attribute <name, value> corresspond to each attribute of
            // GenericObject
            ArrayList<GenericAttribute<?, ?>> attributeList = new ArrayList<GenericAttribute<?, ?>>();
            attributeList = objectList.get( i ).getAttributeList();
            int j = 0;

            String key = "";
            String value = "";

            while ( j < attributeList.size() ) {
                final String attributeName = String.valueOf( attributeList
                        .get( j ).getName() );
                if ( attributeName.compareToIgnoreCase( textAttribute ) == 0 ) {
                    key = String.valueOf( attributeList.get( j ).getValue() );
                }

                if ( attributeName.compareToIgnoreCase( valueAttribute ) == 0 ) {
                    value = String.valueOf( attributeList.get( j ).getValue() );
                }
                j++;
            }

            KeyValue.put( key, value );
        }

        return KeyValue;
    }
}
